gl: Make the glyph cache survive big glyphs
authorMatthias Clasen <mclasen@redhat.com>
Sun, 2 Jun 2019 19:42:14 +0000 (19:42 +0000)
committerMatthias Clasen <mclasen@redhat.com>
Mon, 3 Jun 2019 02:08:36 +0000 (02:08 +0000)
Create an extra atlas of just the right size for
each huge glyph. Not pretty, but works.

gsk/gl/gskglglyphcache.c

index 208ca28e87c241e8099dd53043378d04ed84dd88..d540d76c1ed9373120d2a53d8357056e2e6a25a3 100644 (file)
@@ -33,13 +33,15 @@ static void     glyph_cache_key_free   (gpointer      v);
 static void     glyph_cache_value_free (gpointer      v);
 
 static GskGLGlyphAtlas *
-create_atlas (GskGLGlyphCache *cache)
+create_atlas (GskGLGlyphCache *cache,
+              int              width,
+              int              height)
 {
   GskGLGlyphAtlas *atlas;
 
   atlas = g_new0 (GskGLGlyphAtlas, 1);
-  atlas->width = ATLAS_SIZE;
-  atlas->height = ATLAS_SIZE;
+  atlas->width = MAX (width, ATLAS_SIZE);
+  atlas->height = MAX (height, ATLAS_SIZE);
   atlas->y0 = 1;
   atlas->y = 1;
   atlas->x = 1;
@@ -70,7 +72,6 @@ gsk_gl_glyph_cache_init (GskGLGlyphCache *self,
   self->hash_table = g_hash_table_new_full (glyph_cache_hash, glyph_cache_equal,
                                             glyph_cache_key_free, glyph_cache_value_free);
   self->atlases = g_ptr_array_new_with_free_func (free_atlas);
-  g_ptr_array_add (self->atlases, create_atlas (self));
 
   self->renderer = renderer;
   self->gl_driver = gl_driver;
@@ -167,7 +168,7 @@ add_to_cache (GskGLGlyphCache  *cache,
 
   if (i == cache->atlases->len)
     {
-      atlas = create_atlas (cache);
+      atlas = create_atlas (cache, width + 2, height + 2);
       g_ptr_array_add (cache->atlases, atlas);
     }
 
@@ -223,7 +224,7 @@ render_glyph (const GskGLGlyphAtlas *atlas,
 
   /* TODO: Give glyphs that large their own texture in the proper size. Don't
    *       put them in the atlas at all. */
-  if (surface_width > ATLAS_SIZE || surface_height > ATLAS_SIZE)
+  if (surface_width > atlas->width || surface_height > atlas->height)
     return FALSE;
 
   surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, surface_width, surface_height);